import os
import re
import zipfile


def find_pkg(name):
    # using regular expression to find name in pkg directory
    pkg_path = os.path.dirname(__file__)
    pkg_path += "/pkg"
    for p in list_files(pkg_path, False):
        if check_pattern(p, [name]):
            return pkg_path+"/"+p
    return ""


def get_linux_platform():
    with open("/etc/os-release") as f:
        lines = f.readlines()
    platform = ""
    codename = ""
    version = ""
    for line in lines:
        tmp = line.strip().split('=')
        name = tmp[0]
        if name == "NAME":
            s = tmp[1].replace('"', '').lower()
            platform = s.split()[0]
            continue
        if name == "UBUNTU_CODENAME":
            codename = tmp[1]
            continue
        if name == "VERSION_ID":
            version = tmp[1]
    return platform, codename, version


def _list_dir(dir_path, full_path, list_type):
    # list_type = 1, only file
    # list_type = 2, only dir
    # list_type = others, both file and dir
    dirs = []
    files = []
    if not os.path.exists(dir_path):
        return dirs
    for dp in os.listdir(dir_path):
        dp = os.path.join(dir_path, dp)
        full_dp = os.path.join(dir_path, dp).replace("\\", "/")
        if os.path.isdir(dp):
            if full_path:
                dirs.append(full_dp)
            else:
                dirs.append(dp)
        else:
            if full_path:
                files.append(full_dp)
            else:
                files.append(dp)
    if list_type == 1:
        return files
    elif list_type == 2:
        return dirs
    else:
        return dirs+files


def _list_dir_recursion(dir_path, full_path, ignore_patt, list_type):
    # list_type = 1, only file
    # list_type = 2, only dir
    # list_type = others, both file and dir
    all_dirs = []
    all_files = []

    def filter_list(sub, parent):
        new_sub = sub[:]
        for ns in new_sub:
            nf = parent+"/"+ns
            if check_pattern(nf, ignore_patt):
                sub.remove(ns)

    for here, sub_dirs, files in os.walk(dir_path):
        if check_pattern(here, ignore_patt):
            continue
        here = here.replace("\\", "/")
        filter_list(sub_dirs, here)
        filter_list(files, here)
        if not full_path:
            all_dirs += sub_dirs
            all_files += files
        else:
            for sd in sub_dirs:
                all_dirs.append(here+"/"+sd)
            for f in files:
                all_files.append(here+"/"+f)
    if list_type == 1:
        return all_files
    elif list_type == 2:
        return all_dirs
    else:
        return all_dirs+all_files


def list_files(dir_path, full_path=False, recursion=False, ignore_patt=None):
    if not recursion:
        return _list_dir(dir_path, full_path, 1)
    return _list_dir_recursion(dir_path, full_path, ignore_patt, 1)


def list_dir(dir_path, full_path=False, recursion=False, ignore_patt=None):
    if not recursion:
        return _list_dir(dir_path, full_path, 2)
    return _list_dir_recursion(dir_path, full_path, ignore_patt, 2)


def list_file_dir(dir_path, full_path=False, recursion=False, ignore_patt=None):
    if not recursion:
        return _list_dir(dir_path, full_path, 3)
    return _list_dir_recursion(dir_path, full_path, ignore_patt, 3)


def check_pattern(to_be_check, checker):
    if checker is None:
        return False
    for patt in checker:
        c = re.compile(patt)
        res = c.match(to_be_check)
        if res is not None:
            return True
    return False


def make_zip(save_name, zip_files, source_dir):
    with zipfile.ZipFile(save_name, "w") as f:
        for zf in zip_files:
            f.write(zf, arcname=zf[len(source_dir):])


def unzip(extra_path, zip_path):
    with zipfile.ZipFile(zip_path) as zf:
        zf.extractall(extra_path)


# def zip_encrypt(save_name, zip_files, zip_dir, path_7z, password):
#     subprocess.call([path_7z, ""])
